package com.ggb.reactive.service

import com.ggb.reactive.domain.entity.AddressBook
import lombok.RequiredArgsConstructor
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.stereotype.Service
import reactor.core.publisher.Mono

@Service
@RequiredArgsConstructor
class AddressBookService(
    private val databaseClient: DatabaseClient) {


    /**
     * 更新菜品
     */
    fun update(addressBook: AddressBook): Mono<Long> {
        val updates = listOfNotNull(
            addressBook.userId?.let { "userId = :userId" to it },
            addressBook.consignee?.let { "consignee = :consignee" to it },
            addressBook.phone?.let { "phone = :phone" to it },
            addressBook.sex?.let { "sex = :sex" to it },
            addressBook.provinceCode?.let { "province_code = :provinceCode" to it },
            addressBook.provinceName?.let { "province_name = :provinceName" to it },
            addressBook.cityCode?.let { "city_code = :cityCode" to it },
            addressBook.cityName?.let { "city_name = :cityName" to it },
            addressBook.districtCode?.let { "district_code = :districtCode" to it },
            addressBook.districtName?.let { "district_name = :districtName" to it },
            addressBook.detail?.let { "detail = :detail" to it },
            addressBook.isDefault?.let { "is_default = :isDefault" to it },
            addressBook.label?.let { "label = :label" to it }
        )

        if (updates.isEmpty() || addressBook.id == null) {
            return Mono.just(0L)
        }

        val setClause = updates.joinToString(", ") { it.first }
        val sql = "UPDATE address_book SET $setClause WHERE id = :id"

        var updateSpec = databaseClient.sql(sql)
            .bind("id", addressBook.id!!)

        updates.forEach { (key, value) ->
            // Here we correct the split part to properly extract the named parameter from the SQL snippet
            val paramName = key.substringAfter(" = :")
            updateSpec = updateSpec.bind(paramName, value)
        }

        return updateSpec.fetch().rowsUpdated()
    }

}